import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @Author chenyeqing
 * @Date 2021/7/11 13:17
 */
public class ProxyDemo {
}


class Demo {
    public static void main(String[] args) {
        // 静态代理
        Speaker zhangSanLawyer = new ZhangSanLawyer();
        zhangSanLawyer.speak();

        System.out.println("======");
        // JDK_动态代理：本体必须实现接口
        LawyerProxy lawyerProxy = new LawyerProxy(new ZhangSan());
        Speaker speaker = (Speaker) Proxy.newProxyInstance(Demo.class.getClassLoader(), new Class[]{Speaker.class}, lawyerProxy);
        speaker.speak();

        // CGLIB_动态代理：是JDK代理的补充，不要求本体实现接口
        LawyerInterceptor lawyerInterceptor = new LawyerInterceptor(new LiSi());
        LiSi lisi = (LiSi) Enhancer.create(LiSi.class, lawyerInterceptor);
        lisi.speak();
    }
}


/**
 * 实际对象 - 张三
 */
class ZhangSan implements Speaker {

    @Override
    public void speak() {
        System.out.println("张三说：我老婆打我");
    }
}

/**
 * 实际对象 - 李四
 */
class LiSi {

    public void speak() {
        System.out.println("李四说：我老婆打我");
    }
}

/**
 * 代理类 律师
 */
class ZhangSanLawyer implements Speaker {

    /**
     * 代理张三
     */
    private ZhangSan zhangSan = new ZhangSan();

    @Override
    public void speak() {
        System.out.println("引用法律条文！");
        zhangSan.speak();
        System.out.println("打人是不对的！");
    }
}

/**
 * JDK 动态代理
 */
class LawyerProxy implements InvocationHandler {

    private Object object;

    public LawyerProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("speak".equals(method.getName())) {
            System.out.println("引用法律条文！");
            // 反射 调用实体的原有方法
            method.invoke(object, args);
            System.out.println("打人是不对的！");
        }
        return null;
    }
}

/**
 * CGLIB 动态代理
 */
class LawyerInterceptor implements MethodInterceptor {

    private Object object;

    public LawyerInterceptor(Object object) {
        this.object = object;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if ("speak".equals(method.getName())) {
            System.out.println("引用法律条文！");
            // 反射 调用实体的原有方法
            method.invoke(object, objects);
            System.out.println("打人是不对的！");
        }
        return null;
    }
}

/**
 * 接口
 */
interface Speaker {
    void speak();
}